# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render
from django.http import HttpResponse
from analysis.models import Log
from analysis.regex import pattern_os
import re
from django.db.models import Q, Count, Avg


def logs_insert(request):
    """nginx log 批量入库"""

    # 捕获IO异常及其他异常
    try:
        # with确保发生其他异常时文件最终关闭
        with open('D:/python_demo/nginxlog/analysis/nginx.log', 'r') as f:
            logs = []
            for line in iter(f):
                items = line.strip().split(' | ')

                # 获取不带参数的URL
                request_items = items[3].split(' ')
                request_url = request_items[1].split('?')[0].strip()

                # 匹配 User Agent 中的 OS
                match_obj = re.search(pattern_os, items[8])
                user_os_raw = match_obj.group() if match_obj else 'other'
                user_os = user_os_raw.lower()

                # 获取客户端版本码
                if 'VERSION_CODE' in items[8]:
                    app_version = items[8].split('/')[-1].strip()[:-1]
                else:
                    user_os = 'other'
                    app_version = ''

                # 构造Log对象
                log = Log(request_ip=items[0], some_str=items[1], request_time=items[2],
                          request_method=request_items[0], request_url=request_url,
                          http_version=request_items[2], host=items[4], status_code=items[5],
                          content_length=items[6], refer=items[7], user_os=user_os,
                          app_version=app_version, user_ip=items[9], backend_address=items[10],
                          backend_code=items[11], backend_duration=items[12], response_duration=items[13])
                logs.append(log)

            # 一次插入全部日志
            Log.objects.bulk_create(logs)
            return HttpResponse('<p>Nginx日志入库成功...</p>')
                
    except Exception as e:
        return HttpResponse('<p>Nginx日志入库失败：%s</p>' % e)


def urls_top(request, top_n):
    """访问数 top n 的URL"""

    # 查询android或iOS用户访问数前N的URL
    queryset = Log.objects.filter(~Q(user_os='other')).values('request_url').annotate(
               counts=Count('request_url')).order_by('-counts')[:top_n]

    params = {'queryset': queryset, 'type': 'urls_top'}
    return render(request, 'statistic.html', params)


def ips_top(request, top_n):
    """访问数 top n 的用户IP"""

    # 查询android或iOS用户访问数前N的用户IP
    queryset = Log.objects.filter(~Q(user_os='other')).values('user_ip').annotate(
               counts=Count('user_ip')).order_by('-counts')[:top_n]

    params = {'queryset': queryset, 'type': 'ips_top'}
    return render(request, 'statistic.html', params)


def os_percent(request):
    """统计 android 和 ios 客户端访问数占比"""

    # 查询android和iOS客户端各自的访问数
    queryset = Log.objects.filter(~Q(user_os='other')).values('user_os').annotate(
               counts=Count('user_os'))

    # 查询android和iOS客户端总访问数
    sum_counts = Log.objects.filter(~Q(user_os='other')).count()

    for query in queryset:
        # 不会出现零除异常
        query['percent'] = '%.1f%%' % (float(query['counts']) / sum_counts * 100)

    params = {'queryset': queryset, 'type': 'os_percent'}
    return render(request, 'statistic.html', params)


def version_percent(request):
    """统计 android 和 ios 客户端各自版本的访问数占比"""

    # 以操作系统和APP版本号分组查询android与ios客户端各APP版本号的访问数，并排序
    queryset = Log.objects.filter(~Q(user_os='other')).values('user_os', 'app_version').annotate(
               counts=Count('app_version')).order_by('user_os', '-counts')

    # 查询android和iOS客户端各自的访问数
    android_counts = Log.objects.filter(user_os='android').count()
    ios_counts = Log.objects.filter(user_os='ios').count()

    for query in queryset:
        if query['user_os'] == 'android':
            # android的该APP版本号占android客户端访问数的百分比
            query['percent'] = '%.3f%%' % (float(query['counts']) / android_counts * 100)
        else:
            # ios的该APP版本号占ios客户端访问数的百分比
            query['percent'] = '%.3f%%' % (float(query['counts']) / ios_counts * 100)

    params = {'queryset': queryset, 'type': 'version_percent'}
    return render(request, 'statistic.html', params)


def response_avg(request):
    """统计各响应状态码对应的平均响应时间"""

    # 查询android或ios各响应状态码对应的平均响应时间
    queryset = Log.objects.filter(~Q(user_os='other')).values('status_code').annotate(
               avg=Avg('response_duration')).order_by('avg')

    params = {'queryset': queryset, 'type': 'response_avg'}
    return render(request, 'statistic.html', params)
